package com.mazaiting.instructions.base;

import com.mazaiting.rtda.MtFrame;
import com.mazaiting.rtda.MtSlot;
import com.mazaiting.rtda.MtThread;
import com.mazaiting.rtda.heap.MtMethod;
import lombok.extern.slf4j.Slf4j;

import java.util.Objects;

/**
 * 方法逻辑操作指令
 *
 * @author mazaiting
 * @since 2021/8/24
 */
@Slf4j
public class MethodInvokeLogic {

    /**
     * 调用方法
     * @param frame 栈帧
     * @param method 方法
     */
    public static void invokeMethod(MtFrame frame, MtMethod method) {
        // 获取当前线程
        MtThread thread = frame.getThread();
        // 创建新栈帧
        MtFrame newFrame = thread.newFrame(method);
        // 将新栈帧压入线程
        thread.pushFrame(newFrame);
        // 方法参数槽
        int argSlotCount = method.getArgSlotCount();
        // 判断参数槽是否大于 0
        if (argSlotCount > 0) {
            for (int i = argSlotCount - 1; i >= 0; i--) {
                MtSlot slot = frame.getOperandStack().popSlot();
                newFrame.getLocalVars().setSlot(i, slot);
            }
        }
        // 判断是否为本地方法
        if (method.isNative()) {
            // 跳过注册本地方法
            if (Objects.equals(method.getName(), "registerNatives")) {
                thread.popFrame();
            } else {
                log.debug("native method: {}.{}{}\n", method.getMtClass().getName(), method.getName(), method.getDescriptor());
            }
        }
    }

}


















